package com.fivestar.pmanager.core.util;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

public class DateHelper
{
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_FORMAT_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";
    public static final String DATE_FORMAT_MMDDHHMM = "MM-dd HH:mm";
    public static final String DATE_FORMAT_MMDDHH = "MM月dd日HH时";
    public static final String DATE_FORMAT_YMD = "yyyyMMdd";
    public static final String DATE_HHMM = "HH:mm";
    public static final String DATE_FORMAT_LOGIC_TIMESTAMP_WITHOUT_MSEC = "yyyyMMddHHmmss";

    public static final SimpleDateFormat simpleDate = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
    public static final SimpleDateFormat simpleTime = new SimpleDateFormat(DATE_FORMAT_YYYYMMDDHHMMSS);
    public static final SimpleDateFormat simpleDate2 = new SimpleDateFormat(DATE_FORMAT_MMDDHHMM);
    public static final SimpleDateFormat simpleDate3 = new SimpleDateFormat(DATE_FORMAT_MMDDHH);
    public static final SimpleDateFormat simpleDate4 = new SimpleDateFormat(DATE_FORMAT_YMD);
    public static boolean isValidDate(String dateStr, String dateFmt)
    {
        try
        {
            Date date = convertDate(Locale.CHINA, dateStr, dateFmt);

            if (date == null)
            {
                return false;
            }
            return true;
        }
        catch (Exception exception)
        {
            return false;
        }
    }


    public static Date convertDate(Locale locale, String dateStr, String dateFmt)
    {
        try
        {
            if (locale == null)
            {
                locale = Locale.getDefault();
            }
            SimpleDateFormat dateFmter = new SimpleDateFormat(dateFmt, locale);
            return dateFmter.parse(dateStr);
        }
        catch (Exception exception)
        {
            exception.printStackTrace();
            return null;
        }
    }


    public static String convertDateToString(Date inDate)
    {
        if (inDate == null) return "";

        SimpleDateFormat df = new SimpleDateFormat(DEFAULT_DATE_FORMAT);

        return df.format(inDate);
    }


    public static String convertDateToString(Date inDate, String dateFormat)
    {
        String resultValue = "";

        try
        {
            SimpleDateFormat df = new SimpleDateFormat(dateFormat);
            resultValue = df.format(inDate);
        }
        catch (Exception e)
        {
            return null;
        }

        return resultValue;
    }


    public static String formatDate(Locale locale, Date date, String dateFmt)
    {
        try
        {
            SimpleDateFormat dateFmter = new SimpleDateFormat(dateFmt, locale);
            return dateFmter.format(date);
        }
        catch (Exception exception)
        {
            return null;
        }
    }


    public static String formatDate(Date date, String dateFormat)
    {
        return formatDate(Locale.CHINA, date, dateFormat);
    }


    public static String formatDate(long millisecond, String dateFormat)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millisecond);
        return formatDate(null, calendar.getTime(), dateFormat);
    }


    public static int compareDate(Date date1, Date date2)
    {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        return calendar1.compareTo(calendar2);
    }


    /**
     * 
     * validate date overlap.
     * 
     * @author WangLiming
     * @return if overlap will return 1,else return 0
     * @throws
     */
    public static int dateOverlap(Date startDate1, Date endDate1,
            Date startDate2, Date endDate2)
    {
        if (startDate1.compareTo(endDate2) > 0
                || endDate1.compareTo(startDate2) < 0)
        {
            return 0;
        }
        return 1;
    }


    public static long getCurrentTimeStamp()
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        return calendar.getTimeInMillis();
    }


    public static Date getLastTimeOfDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }


    public static Date getFirstTimeOfDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        calendar.set(Calendar.MINUTE, 00);
        calendar.set(Calendar.SECOND, 00);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTime();
    }


    public static Date getFirstDateOfMonth(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 01);
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        calendar.set(Calendar.MINUTE, 00);
        calendar.set(Calendar.SECOND, 00);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTime();
    }


    public static Date addYearToDate(Date date, int year)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }


    public static Date addMonthToDate(Date date, int month)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }


    public static Date addDayToDate(Date date, int day)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 时间加小时处理
     * @param date
     * @param hour
     * @return
     */
    public static Date addHourToDate(Date date, int hour)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 时间加分钟处理
     * @param date
     * @param minute
     * @return
     */
    public static Date addMinuteToDate(Date date, int minute)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 时间加秒数处理
     * @param date
     * @param second
     * @return
     */
    public static Date addSecondToDate(Date date, int second)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    public static Date addTimeToDate(Date date, String time)
    {
        String dateTime = DateHelper.convertDateToString(date, DEFAULT_DATE_FORMAT) + " " + time;
        return DateHelper.convertDate(dateTime, DATE_FORMAT_YYYYMMDDHHMMSS);
    }

    public static String getDateString(Date date, String time)
    {
        return DateHelper.convertDateToString(date, DEFAULT_DATE_FORMAT) + " " + time;
    }

    public static int getMonthFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }


    public static int getDayFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }


    public static int getHourFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR);
    }


    public static int getWeekDayFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * get days between startTime and secondTime.
     * 
     * @return int
     * @throws
     */
    public static int getDaysBetween(java.util.Calendar d1,
            java.util.Calendar d2)
    {
        if (d1.after(d2))
        { // swap dates so that d1 is start and d2 is end
            java.util.Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(java.util.Calendar.DAY_OF_YEAR)
                - d1.get(java.util.Calendar.DAY_OF_YEAR);
        int y2 = d2.get(java.util.Calendar.YEAR);
        if (d1.get(java.util.Calendar.YEAR) != y2)
        {
            d1 = (java.util.Calendar) d1.clone();
            do
            {
                days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
                d1.add(java.util.Calendar.YEAR, 1);
            }
            while (d1.get(java.util.Calendar.YEAR) != y2);
        }
        return days;
    }


    /**
     * get the date list between two days, includes these two days.
     * 
     * @return List
     * @throws
     */
    public static List<Date> getDaysListBetween(java.util.Calendar d1,
            java.util.Calendar d2)
    {
        List<Date> days = new ArrayList<Date>();
        if (d1.after(d2))
        { // swap dates so that d1 is start and d2 is end
            java.util.Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        d1 = (java.util.Calendar) d1.clone();
        do
        {
            days.add(d1.getTime());
            d1.add(java.util.Calendar.DAY_OF_YEAR, 1);
        }
        while (d1.get(java.util.Calendar.YEAR) != d1
                .get(java.util.Calendar.YEAR)
                || d1.get(java.util.Calendar.DAY_OF_YEAR) != (d2
                        .get(java.util.Calendar.DAY_OF_YEAR) + 1));
        return days;
    }


    public static int getMinuteFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }


    public static int getSecondFromDate(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }


    public static Date convertDate(String dateStr, String dateFmt)
    {
        return convertDate(Locale.CHINA, dateStr, dateFmt);
    }


    public static int getDayOfYear(Date date)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_YEAR);
    }


    // format:yyyy-mm-dd 00:00:00
    public static Date getCurrentDate()
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date paramCurrDate = calendar.getTime();
        return paramCurrDate;
    }

    /**
     * 今天开始时间
     * @return
     */
    public static String getTodayStartTime(){
        return simpleDate.format(new Date())+" 00:00:00";
    }
    
    /**
     * 第n天开始时间
     * @return
     */
    public static String getFewStartTime(int i){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, i);
        return simpleDate.format(calendar.getTime())+" 00:00:00";
    }

    /**
     * 昨天开始时间
     * @return
     */
    public static String getYesterdayStartTime(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        return simpleDate.format(calendar.getTime())+" 00:00:00";
    }

    /**
     * 昨天开始时间
     * @return
     */
    public static Date getYesterday(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    public static Long convertSecondsToMillisecond(Long seconds)
    {
        return seconds * 1000;
    }


    public static Long convertMillisecondToSeconds(Long millisecond)
    {
        return millisecond / 1000;
    }
    
    //将秒数转换成Date类型
    public static Date convertSecondsToDate(Long seconds)
    {
        return new Date(convertSecondsToMillisecond(seconds));
    }

    /**
     * 
     * 根据设置的年月日来获取日期.
     *
     * @param year  年
     * @param month 月
     * @param date 日期 
     * @return
     */
    public static Date getDate(int year, int month, int date) 
    {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, date);
        return calendar.getTime();
    }
    
    public static Date getFirstDateOfWeek()
    {
    	int mondayPlus;
    	Calendar cd = Calendar.getInstance();
    	// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
    	int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
    	if (dayOfWeek == 1) {
    		mondayPlus = 0;
    	} else {
    		mondayPlus = 1 - dayOfWeek;
    	}
    	GregorianCalendar currentDate = new GregorianCalendar();
    	currentDate.add(GregorianCalendar.DATE, mondayPlus);
    	currentDate.set(Calendar.HOUR_OF_DAY, 00);
    	currentDate.set(Calendar.MINUTE, 00);
    	currentDate.set(Calendar.SECOND, 00);
    	currentDate.set(Calendar.MILLISECOND, 000);
    	Date monday = currentDate.getTime();
    	return monday;
    }

    /**
     * 输入当前时间
     * @param d 当前时间
     * @param day 向后数的天数
     * @param hour 指定小时数
     * @param minute  指定分钟数
     * @param addMinute 相差时间
     * @return
     */
    public static Date convertDate(Date d, int day,int hour,int minute ,int addMinute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.add(Calendar.DAY_OF_MONTH,  day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.add(Calendar.MINUTE,-addMinute);
        return calendar.getTime();
    }
    
    /**
	 * 
	 * 获取相差月份
	 * @param time1 201501
	 * @param time2 201512
	 * @return
	 */
	public static int getDiffMonths(String time1 ,String time2){
		int year1 = Integer.valueOf(time1.substring(0,4));
		int year2 = Integer.valueOf(time2.substring(0,4));
		int month1 = Integer.valueOf(time1.substring(4));
		int month2 = Integer.valueOf(time2.substring(4));
		int m = (year1-year2)*12 + month1 - month2;
		return Math.abs(m)+1;
	}


    /**
     * 计算2个时间点相差多少个小时
     * 一个小数位
     *
     * @param startTime
     * @param endTime
     * @return double
     */
    public static double getDiffHours(Date startTime, Date endTime){
        BigDecimal dec = BigDecimal.valueOf((endTime.getTime()-startTime.getTime())/(1000*60));
        return dec.divide(new BigDecimal(60),1,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 计算2个时间点相差多少个小时
     * 一个小数位
     *
     * @param startTime
     * @param endTime
     * @return double
     */
    public static double getDiffHours(Date startTime, Date endTime, Double hours){
        BigDecimal dec = BigDecimal.valueOf((endTime.getTime()-startTime.getTime())/(1000*60));
        dec = dec.divide(new BigDecimal(60),1,BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(hours));
        return dec.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 转换月份数字
     * @param number
     * @return
     */
    public static String convertMonthNumber(int number){
        switch (number){
            case 1:
                return "一月";
            case 2:
                return "二月";
            case 3:
                return "三月";
            case 4:
                return "四月";
            case 5:
                return "五月";
            case 6:
                return "六月";
            case 7:
                return "七月";
            case 8:
                return "八月";
            case 9:
                return "九月";
            case 10:
                return "十月";
            case 11:
                return "十一月";
            case 12:
                return "十二月";
        }
        return "";
    }

}
